<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use Azure;
use App;
use Config;
use Request;
use Response;
use Redirect;
use WindowsAzure\Table\Models\Entity;
use WindowsAzure\Table\Models\EdmType;
use WindowsAzure\Common\ServiceException;
use WindowsAzure\Common\ServicesBuilder;
use Log;

class TablesController extends Controller
{


    var $table;

    public function __construct()
    {
        Log::info(session('access-key'));

        if (session()->has('account') && session()->has('access-key')) {
            $connection = "DefaultEndpointsProtocol=https;AccountName=" . session('account') . ";AccountKey=" . session('access-key');
            Log::info(session('access-key'));
            $this->table = ServicesBuilder::getInstance()->createTableService($connection);
        }
        else {
            session()->flash('status', 'Please Log in');
            return Redirect::to('/')->send();
        }
    }

    /**
     * Index of the table
     * @return \Illuminate\View\View    Returns the view of the table
     */
    public function index()
    {
        $data['title'] = "Tables";
        $data['heading'] = "Tables";
        return view('tables', $data);
    }

    /**
     *  Create new table. It takes the arguments from the POST or GET.
     */
    public function createTable()
    {
        $data = Request::all();
        try {
            // Create table.
            $this->table->createTable($data['table']);
            $data['statusCode'] = 200;
            return json_encode($data);
        }
        catch (ServiceException $e) {
            $code = $e->getCode();
            $error_message = $e->getMessage();
            $data['statusCode'] = 400;
            $data['errorMessage'] = $error_message;
            return json_encode($data);
            // Handle exception based on error codes and messages.
            // Error codes and messages can be found here:
            // http://msdn.microsoft.com/library/azure/dd179438.aspx
        }
    }

    public function viewEntities($tableName, $partitionKey)
    {
        $filter = "PartitionKey eq " . "'" . $partitionKey . "'";
        try {
            $result = $this->table->queryEntities($tableName, $filter);
        }
        catch (ServiceException $e) {
            // Handle exception based on error codes and messages.
            // Error codes and messages are here:
            // http://msdn.microsoft.com/library/azure/dd179438.aspx
            $code = $e->getCode();
            $error_message = $e->getMessage();
            echo $code . ": " . $error_message . "<br />";
        }

        $entities = $result->getEntities();
        foreach ($entities as $entity) {
            echo $entity->getPartitionKey() . ":" . $entity->getRowKey() . "<br />";
        }
    }


    public function createEntity()
    {
        $data['title'] = "Entity";
        $data['heading'] = "Create Entity";
        return view('addentity', $data);
    }

    /**
     * This function creates entity based on the number of values given
     *
     * @param $tableName    Table Name in which the enitity should be created
     * @param $partitionKey Partition name for the entity
     * @return string       Returns the json with the status code, 200 in case of success
     */
    public function createEntityProcess($tableName, $partitionKey)
    {
        $data = Request::all();
        $fields = count($data) / 2;
        // Create new Entity and set basic variables
        $entity = new Entity();
        $entity->setPartitionKey($partitionKey);
        $entity->setRowKey(sha1(microtime(true) . mt_rand(10000, 90000)));

        for ($i = 1; $i <= $fields; $i++) {
            $entity->addProperty($data['key-' . $i], EdmType::STRING, $data['value-' . $i]);
        }

        try {
            $data['data'] = $this->table->insertEntity($tableName, $entity);
            $data['statusCode'] = 200;
            return json_encode($data);
        }
        catch (ServiceException $e) {
            // Handle exception based on error codes and messages.
            // Error codes and messages are here:
            // http://msdn.microsoft.com/library/azure/dd179438.aspx
            $code = $e->getCode();
            $error_message = $e->getMessage();
            $data['statusCode'] = 400;
            $data['errorMessage'] = $error_message;
            return json_encode($data);
        }

    }


    /**
     *  The function gets the entites based on the table name and partition key
     * @param $tableName    Table name from which the entities should be received
     * @param $partitionKey Partition key for which entities we are looking for
     * @return string       Returns the view with the resulting values
     */
    public function getEntities($tableName, $partitionKey)
    {
        $filter = "PartitionKey eq " . "'" . $partitionKey . "'";

        try {
            $result = $this->table->queryEntities($tableName, $filter);
        }
        catch (ServiceException $e) {
            // Handle exception based on error codes and messages.
            // Error codes and messages are here:
            // http://msdn.microsoft.com/library/azure/dd179438.aspx
            $code = $e->getCode();
            $error_message = $e->getMessage();
            echo $code . ": " . $error_message . "<br />";
        }

        $entities = $result->getEntities();
        $data['entities'] = $entities;
        $renderedView = view('renders.entity', $data)->render();
        $v['title'] = "Entities";
        $v['heading'] = "Entities ";
        $v['table'] = $tableName;
        $v['partition'] = $partitionKey;
        $v['results'] = count($entities);
        $v['view'] = $renderedView;
        return view('entities', $v);
    }

    public function getEntitiesAjax($tableName, $partitionKey)
    {
        $filter = "PartitionKey eq " . "'" . $partitionKey . "'";

        try {
            $result = $this->table->queryEntities($tableName, $filter);
            $data['statusCode'] = 200;
            $entities = $result->getEntities();
            $data['entities'] = $entities;
            $renderedView = view('renders.entity', $data)->render();
            $data['view'] = $renderedView;
            return json_encode($data);
        }
        catch (ServiceException $e) {
            // Handle exception based on error codes and messages.
            // Error codes and messages are here:
            // http://msdn.microsoft.com/library/azure/dd179438.aspx
            $code = $e->getCode();
            $error_message = $e->getMessage();
            $data['statusCode'] = 400;
            $data['errorMessage'] = $error_message;
            return json_encode($data);
        }
    }

    /**
     * This function deletes the entity based on tablename,partitionkey and rowkey
     * @param $tableName    The name of the table
     * @param $partitionKey Partition key in which entity exists
     * @param $rowKey       Row key of the particular entity
     * @return string       Returns json encoded statusCode and errorMessage in case of error
     */
    public function deleteEntity($tableName, $partitionKey, $rowKey)
    {
        try {
            // Delete entity.
            $this->table->deleteEntity($tableName, $partitionKey, $rowKey);
            $data['statusCode'] = 200;
            return json_encode($data);
        }
        catch (ServiceException $e) {
            // Handle exception based on error codes and messages.
            // Error codes and messages are here:
            // http://msdn.microsoft.com/library/azure/dd179438.aspx
            $code = $e->getCode();
            $error_message = $e->getMessage();
            $data['statusCode'] = 400;
            $data['errorMessage'] = $error_message;
            return json_encode($data);
        }
    }

    public function editEntity($tableName, $partitionKey, $rowKey)
    {
        try {
            $result = $this->table->getEntity($tableName, $partitionKey, $rowKey);
            $data['entity'] = $result->getEntity();
            $data['title'] = "Edit Entity";
            $data['heading'] = "Edit Entity";
            $data['table'] = $tableName;
            return view('editentity', $data);
        }
        catch (ServiceException $e) {
            // Handle exception based on error codes and messages.
            // Error codes and messages are here:
            // http://msdn.microsoft.com/library/azure/dd179438.aspx
            $code = $e->getCode();
            $error_message = $e->getMessage();
            echo $code . ": " . $error_message . "<br />";
        }
    }

    public function editEntityProcess()
    {
        $data = Request::all();
        $result = $this->table->getEntity($data['table'], $data['PartitionKey'], $data['RowKey']);
        $entity = $result->getEntity();
        $keys = array_keys($data);

        foreach ($keys as $key) {
            if ($key != 'PartitionKey' || $key != 'RowKey') {
                $entity->setPropertyValue($key, $data[$key]); //Removed Location.
            }
        }
        try {
            $this->table->updateEntity($data['table'], $entity);
            $msg['statusCode'] = 200;
            return json_encode($msg);
        }
        catch (ServiceException $e) {
            // Handle exception based on error codes and messages.
            // Error codes and messages are here:
            // http://msdn.microsoft.com/library/azure/dd179438.aspx
            $code = $e->getCode();
            $error_message = $e->getMessage();
            $msg['statusCode'] = 400;
            $msg['errorMessage'] = $error_message;
            return json_encode($msg);
        }
    }
}
